package com.itheima;

import com.itheima.service.MyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

/*
    注意几点
    1. 版本选择了 java 8, 因为目前的 aspectj-maven-plugin 1.14.0 最高只支持到 java 16
    2. 一定要用 maven 的 compile 来编译, idea 不会调用 ajc 编译器
 */

/*
* 通过下面的两种方式，我们是想要了解spring里面aop的原理，所以我们采用了这样的方式
* 通过打印可以看到MyService的类还是service class: class com.itheima.service.MyService
* 并不是什么cglib$$等等，也就是动态代理的结果
* 其实这里我们并没有用动态代理来实现，而是使用了aspectj的编译器来操作增强
* 编译器的原理就是把MyService的类改写了，虽然我们源代码只有一行foo()方法，
* 但是改写后的class已经加入了前置增强，我们可以看对应的class文件
* 我们可以看到确实是改写了class，既然class被改写了，根spring容器就没有关系了
* ---
* 我们注意一个细节，MyAspect切面类并没有@Component注解，也就是并没有交给spring进行管理
* 是aspect的一个编译器来读取到这个切面，来进行增强，并不是spring来进行增强
* ---
* 如何实现上面演示的那个效果嘞，其实我们加一个插件在pom文件里面，就可以实现那样的效果
*
* 也就是说，我们使用aspectj的编译器也可以实现aop的功能增强，并且通过这样不管是静态方法还是动态方法，
* 我们都可以对该方法进行增强，因为我们是通过修改class文件来操作的
*
* */
@SpringBootApplication
public class A09 {

    private static final Logger log = LoggerFactory.getLogger(A09.class);

    public static void main(String[] args) {

        /*方式1*/
        ConfigurableApplicationContext context = SpringApplication.run(A09.class, args);
        MyService service = context.getBean(MyService.class);
        log.debug("service class: {}", service.getClass());
        service.foo();
        context.close();

        /*方式2*/
//        new MyService().foo();

    }
}
